// Listen for messages from the popup
chrome.runtime.onMessage.addListener(function(request, sender, sendResponse) {
  if (request.action === 'extractSubtitles') {
    extractYouTubeSubtitles()
      .then(subtitles => {
        sendResponse({success: true, subtitles: subtitles});
      })
      .catch(error => {
        sendResponse({success: false, error: error.message});
      });
    
    // Return true to indicate we will send a response asynchronously
    return true;
  } else if (request.action === 'getVideoInfo') {
    try {
      const videoInfo = getYouTubeVideoInfo();
      sendResponse(videoInfo);
    } catch (error) {
      sendResponse({error: error.message});
    }
    return true;
  }
});

/**
 * Get YouTube video information (title, channel, etc.)
 * @returns {Object} Video information
 */
function getYouTubeVideoInfo() {
  // Get video title
  const titleElement = document.querySelector('h1.title.style-scope.ytd-video-primary-info-renderer') || 
                      document.querySelector('h1.ytd-watch-metadata') ||
                      document.querySelector('h1');
  
  // Get channel name
  const channelElement = document.querySelector('div#owner-name a') || 
                        document.querySelector('ytd-channel-name a') ||
                        document.querySelector('a.ytd-channel-name');
  
  return {
    title: titleElement ? titleElement.textContent.trim() : 'Unknown Video',
    channel: channelElement ? channelElement.textContent.trim() : 'Unknown Channel',
    url: window.location.href
  };
}

/**
 * Extract subtitles from the current YouTube video
 * This function attempts multiple methods to get subtitles:
 * 1. By fetching the complete transcript using YouTube's timedtext API
 * 2. From the transcript panel if it's open
 * 3. By opening the transcript panel if it's closed
 * 4. By fetching the captions track directly if available
 * 5. By using YouTube's new transcript UI elements
 */
async function extractYouTubeSubtitles() {
  // Check if we're on a YouTube video page
  if (!window.location.href.includes('youtube.com/watch')) {
    throw new Error('Not a YouTube video page');
  }
  
  console.log('Attempting to extract YouTube subtitles...');
  
  // Method 0: Try to get complete subtitles using timedtext API
  let subtitles = await getCompleteSubtitles();
  if (subtitles) {
    console.log('Successfully extracted complete subtitles using timedtext API');
    return subtitles;
  }
  
  // Method 1: Try to get subtitles from an already open transcript panel
  subtitles = getSubtitlesFromOpenTranscript();
  if (subtitles) {
    console.log('Successfully extracted subtitles from open transcript panel');
    return subtitles;
  }
  
  // Method 2: Try to open the transcript panel and get subtitles
  subtitles = await openTranscriptAndGetSubtitles();
  if (subtitles) {
    console.log('Successfully extracted subtitles after opening transcript panel');
    return subtitles;
  }
  
  // Method 3: Try to get subtitles from the video's caption track
  subtitles = await getSubtitlesFromCaptionTrack();
  if (subtitles) {
    console.log('Successfully extracted subtitles from caption track');
    return subtitles;
  }
  
  // Method 4: Try to use YouTube's new transcript UI
  subtitles = await getSubtitlesFromNewYouTubeUI();
  if (subtitles) {
    console.log('Successfully extracted subtitles from new YouTube UI');
    return subtitles;
  }
  
  // Method 5: Try to use YouTube's API data
  subtitles = await getSubtitlesFromPlayerData();
  if (subtitles) {
    console.log('Successfully extracted subtitles from player data');
    return subtitles;
  }
  
  console.error('All subtitle extraction methods failed');
  throw new Error('Could not find subtitles for this video');
}

/**
 * Get complete subtitles for the entire video using YouTube's timedtext API
 */
async function getCompleteSubtitles() {
  console.log('Trying to get complete subtitles using timedtext API...');
  
  try {
    // Get video ID
    const videoId = getYouTubeVideoId();
    if (!videoId) {
      console.log('Could not find video ID');
      return null;
    }
    
    console.log(`Found video ID: ${videoId}`);
    
    // First, try to get the available caption tracks
    const tracksUrl = `https://www.youtube.com/api/timedtext?v=${videoId}&type=list`;
    console.log(`Fetching available caption tracks from: ${tracksUrl}`);
    
    const tracksResponse = await fetch(tracksUrl);
    const tracksXml = await tracksResponse.text();
    
    // Parse the XML to find available tracks
    const parser = new DOMParser();
    const tracksDoc = parser.parseFromString(tracksXml, 'text/xml');
    const trackElements = tracksDoc.getElementsByTagName('track');
    
    console.log(`Found ${trackElements.length} caption tracks`);
    
    if (trackElements.length === 0) {
      console.log('No caption tracks found');
      return null;
    }
    
    // Try to find the best track (prefer English or auto-generated)
    let selectedTrack = null;
    let fallbackTrack = null;
    
    for (let i = 0; i < trackElements.length; i++) {
      const track = trackElements[i];
      const langCode = track.getAttribute('lang_code');
      const langName = track.getAttribute('lang_original');
      const isAutoGenerated = track.getAttribute('name') === 'a.en';
      
      console.log(`Track ${i}: lang=${langCode}, name=${langName}, auto=${isAutoGenerated}`);
      
      // Prefer English tracks
      if (langCode === 'en') {
        if (!isAutoGenerated) {
          // Manual English track is the best option
          selectedTrack = track;
          break;
        } else if (!selectedTrack) {
          // Auto-generated English is good too
          selectedTrack = track;
        }
      }
      
      // Save the first track as fallback
      if (i === 0) {
        fallbackTrack = track;
      }
    }
    
    // If no English track found, use the fallback
    if (!selectedTrack && fallbackTrack) {
      selectedTrack = fallbackTrack;
    }
    
    if (!selectedTrack) {
      console.log('No suitable caption track found');
      return null;
    }
    
    // Get the track parameters
    const langCode = selectedTrack.getAttribute('lang_code');
    const langName = selectedTrack.getAttribute('lang_original');
    const name = selectedTrack.getAttribute('name') || '';
    
    console.log(`Selected track: lang=${langCode}, name=${langName}`);
    
    // Construct the URL to fetch the complete captions
    let captionUrl = `https://www.youtube.com/api/timedtext?v=${videoId}&lang=${langCode}`;
    
    // Add name parameter if it exists (for auto-generated captions)
    if (name) {
      captionUrl += `&name=${name}`;
    }
    
    console.log(`Fetching complete captions from: ${captionUrl}`);
    
    // Fetch the captions
    const captionResponse = await fetch(captionUrl);
    const captionXml = await captionResponse.text();
    
    // Parse the XML and extract text
    const captionDoc = parser.parseFromString(captionXml, 'text/xml');
    const textElements = captionDoc.getElementsByTagName('text');
    
    console.log(`Found ${textElements.length} caption segments`);
    
    if (textElements.length === 0) {
      console.log('No caption segments found');
      return null;
    }
    
    // Extract all text segments with timestamps
    let subtitlesText = '';
    for (let i = 0; i < textElements.length; i++) {
      const text = textElements[i].textContent.trim();
      if (text) {
        subtitlesText += text + ' ';
      }
    }
    
    if (subtitlesText.trim()) {
      return subtitlesText.trim();
    }
    
    return null;
  } catch (error) {
    console.error('Error getting complete subtitles:', error);
    return null;
  }
}

/**
 * Get subtitles from an already open transcript panel
 */
function getSubtitlesFromOpenTranscript() {
  console.log('Trying to get subtitles from open transcript panel...');
  
  // Try multiple selectors for transcript items
  const selectors = [
    'ytd-transcript-segment-renderer',
    'yt-transcript-segment-renderer',
    '.segment-text',
    '.ytd-transcript-segment-renderer',
    '.ytp-caption-segment'
  ];
  
  for (const selector of selectors) {
    const transcriptItems = document.querySelectorAll(selector);
    console.log(`Found ${transcriptItems.length} items with selector: ${selector}`);
    
    if (transcriptItems && transcriptItems.length > 0) {
      let subtitlesText = '';
      
      transcriptItems.forEach(item => {
        // Try different ways to get the text content
        const textElement = item.querySelector('#content') || 
                           item.querySelector('.segment-text') || 
                           item;
        
        if (textElement && textElement.textContent) {
          subtitlesText += textElement.textContent.trim() + ' ';
        }
      });
      
      if (subtitlesText.trim()) {
        return subtitlesText.trim();
      }
    }
  }
  
  console.log('No open transcript panel found or it\'s empty');
  return null;
}

/**
 * Open the transcript panel and get subtitles
 */
async function openTranscriptAndGetSubtitles() {
  console.log('Trying to open transcript panel...');
  
  // Try to find the "..." button (more actions)
  const moreActionsButton = document.querySelector('button.ytp-button[aria-label="More actions"]') || 
                           document.querySelector('.ytp-settings-button') ||
                           document.querySelector('[aria-label="More actions"]');
  
  if (moreActionsButton) {
    console.log('Found more actions button, clicking it...');
    moreActionsButton.click();
    
    // Wait for the menu to appear
    await new Promise(resolve => setTimeout(resolve, 1000));
    
    // Find and click the "Show transcript" option
    // Try multiple selectors and text patterns
    const menuItems = document.querySelectorAll('.ytp-menuitem, .ytp-panel-menu-item, [role="menuitem"]');
    console.log(`Found ${menuItems.length} menu items`);
    
    let transcriptButton = null;
    const transcriptKeywords = ['transcript', '字幕', '文字稿', '记录', 'subtitles', 'captions'];
    
    for (const item of menuItems) {
      const label = item.querySelector('.ytp-menuitem-label') || item;
      const labelText = label.textContent.toLowerCase();
      
      if (label && transcriptKeywords.some(keyword => labelText.includes(keyword))) {
        transcriptButton = item;
        console.log(`Found transcript button with text: ${labelText}`);
        break;
      }
    }
    
    if (transcriptButton) {
      console.log('Clicking transcript button...');
      transcriptButton.click();
      
      // Wait for the transcript panel to load
      await new Promise(resolve => setTimeout(resolve, 2000));
      
      // Try to get subtitles from the now-open transcript panel
      return getSubtitlesFromOpenTranscript();
    } else {
      console.log('Could not find transcript button in menu');
    }
  } else {
    console.log('Could not find more actions button');
  }
  
  // Try alternative method: look for transcript button directly
  const transcriptBtn = document.querySelector('[aria-label="Open transcript"]') || 
                       document.querySelector('.ytd-watch-flexy button[aria-label*="transcript" i]') ||
                       document.querySelector('button[aria-label*="字幕" i]');
  
  if (transcriptBtn) {
    console.log('Found direct transcript button, clicking it...');
    transcriptBtn.click();
    
    // Wait for the transcript panel to load
    await new Promise(resolve => setTimeout(resolve, 2000));
    
    // Try to get subtitles from the now-open transcript panel
    return getSubtitlesFromOpenTranscript();
  }
  
  console.log('Could not open transcript panel');
  return null;
}

/**
 * Get subtitles from the video's caption track
 * This is a fallback method that attempts to find the captions URL
 * from the YouTube player data
 */
async function getSubtitlesFromCaptionTrack() {
  console.log('Trying to get subtitles from caption track...');
  
  try {
    // Try to find the YouTube player object
    if (typeof ytplayer !== 'undefined' && ytplayer.config) {
      console.log('Found ytplayer.config');
      
      let playerResponse;
      
      // Different ways to access player response
      if (ytplayer.config.args && ytplayer.config.args.player_response) {
        playerResponse = JSON.parse(ytplayer.config.args.player_response);
      } else if (ytplayer.config.playerResponse) {
        playerResponse = ytplayer.config.playerResponse;
      } else if (ytplayer.config.args && ytplayer.config.args.raw_player_response) {
        playerResponse = JSON.parse(ytplayer.config.args.raw_player_response);
      }
      
      if (playerResponse) {
        console.log('Found player response');
        const captions = playerResponse.captions;
        
        if (captions && captions.playerCaptionsTracklistRenderer) {
          const captionTracks = captions.playerCaptionsTracklistRenderer.captionTracks;
          
          if (captionTracks && captionTracks.length > 0) {
            // Get the first available caption track
            const captionTrack = captionTracks[0];
            const captionUrl = captionTrack.baseUrl;
            
            console.log(`Found caption URL: ${captionUrl}`);
            
            // Fetch the captions
            const response = await fetch(captionUrl);
            const captionXml = await response.text();
            
            // Parse the XML and extract text
            const parser = new DOMParser();
            const xmlDoc = parser.parseFromString(captionXml, 'text/xml');
            const textElements = xmlDoc.getElementsByTagName('text');
            
            let subtitlesText = '';
            for (let i = 0; i < textElements.length; i++) {
              subtitlesText += textElements[i].textContent.trim() + ' ';
            }
            
            if (subtitlesText.trim()) {
              return subtitlesText.trim();
            }
          }
        }
      }
    }
  } catch (error) {
    console.error('Error getting subtitles from caption track:', error);
  }
  
  console.log('Could not get subtitles from caption track');
  return null;
}

/**
 * Try to get subtitles from YouTube's new UI elements
 */
async function getSubtitlesFromNewYouTubeUI() {
  console.log('Trying to get subtitles from new YouTube UI...');
  
  try {
    // Try to find the transcript button in the new UI
    const engagementPanels = document.querySelectorAll('ytd-engagement-panel-section-list-renderer');
    console.log(`Found ${engagementPanels.length} engagement panels`);
    
    for (const panel of engagementPanels) {
      // Check if this is the transcript panel
      const targetId = panel.getAttribute('target-id');
      if (targetId && targetId.includes('transcript')) {
        console.log('Found transcript panel in engagement panels');
        
        // Check if it's already expanded
        if (panel.hasAttribute('visibility') && panel.getAttribute('visibility') !== 'ENGAGEMENT_PANEL_VISIBILITY_EXPANDED') {
          // Try to expand it
          const expandButton = panel.querySelector('#button, #expand-button, [aria-label="Show transcript"]');
          if (expandButton) {
            console.log('Clicking expand button for transcript panel');
            expandButton.click();
            await new Promise(resolve => setTimeout(resolve, 1000));
          }
        }
        
        // Look for transcript items
        const transcriptItems = panel.querySelectorAll('yt-formatted-string.segment-text');
        console.log(`Found ${transcriptItems.length} transcript items in panel`);
        
        if (transcriptItems && transcriptItems.length > 0) {
          let subtitlesText = '';
          
          transcriptItems.forEach(item => {
            if (item.textContent) {
              subtitlesText += item.textContent.trim() + ' ';
            }
          });
          
          if (subtitlesText.trim()) {
            return subtitlesText.trim();
          }
        }
      }
    }
    
    // Try to find and click the transcript button if not already open
    const transcriptButton = document.querySelector('button[aria-label="Show transcript"], button[aria-label="显示文字记录"]');
    if (transcriptButton) {
      console.log('Found transcript button in new UI, clicking it...');
      transcriptButton.click();
      
      // Wait for the transcript panel to load
      await new Promise(resolve => setTimeout(resolve, 2000));
      
      // Try again to find transcript items
      const transcriptItems = document.querySelectorAll('yt-formatted-string.segment-text, ytd-transcript-segment-renderer');
      console.log(`Found ${transcriptItems.length} transcript items after clicking button`);
      
      if (transcriptItems && transcriptItems.length > 0) {
        let subtitlesText = '';
        
        transcriptItems.forEach(item => {
          if (item.textContent) {
            subtitlesText += item.textContent.trim() + ' ';
          }
        });
        
        if (subtitlesText.trim()) {
          return subtitlesText.trim();
        }
      }
    }
  } catch (error) {
    console.error('Error getting subtitles from new YouTube UI:', error);
  }
  
  console.log('Could not get subtitles from new YouTube UI');
  return null;
}

/**
 * Try to extract subtitles from YouTube player data
 */
async function getSubtitlesFromPlayerData() {
  console.log('Trying to get subtitles from player data...');
  
  try {
    // Try to find video ID
    const videoId = getYouTubeVideoId();
    if (!videoId) {
      console.log('Could not find video ID');
      return null;
    }
    
    console.log(`Found video ID: ${videoId}`);
    
    // Try to extract initial data from the page
    const initialDataScript = Array.from(document.scripts).find(script => 
      script.textContent.includes('window["ytInitialData"]') || 
      script.textContent.includes('var ytInitialData')
    );
    
    if (initialDataScript) {
      console.log('Found ytInitialData script');
      
      // Extract the JSON data
      const scriptContent = initialDataScript.textContent;
      const dataMatch = scriptContent.match(/(?:window\["ytInitialData"\]|var ytInitialData)\s*=\s*({.+?});/);
      
      if (dataMatch && dataMatch[1]) {
        const initialData = JSON.parse(dataMatch[1]);
        
        // Navigate through the data structure to find transcript data
        // This is complex and may change with YouTube updates
        const transcriptData = findTranscriptDataInInitialData(initialData);
        
        if (transcriptData) {
          console.log('Found transcript data in ytInitialData');
          return transcriptData;
        }
      }
    }
    
    // If we couldn't get it from the page, try a direct API request
    // Note: This might not work due to CORS restrictions
    try {
      const timedTextUrl = `https://www.youtube.com/api/timedtext?v=${videoId}&lang=en`;
      console.log(`Trying direct API request to: ${timedTextUrl}`);
      
      const response = await fetch(timedTextUrl);
      const xmlText = await response.text();
      
      if (xmlText && xmlText.includes('<text')) {
        console.log('Got response from timedtext API');
        
        // Parse the XML
        const parser = new DOMParser();
        const xmlDoc = parser.parseFromString(xmlText, 'text/xml');
        const textElements = xmlDoc.getElementsByTagName('text');
        
        let subtitlesText = '';
        for (let i = 0; i < textElements.length; i++) {
          subtitlesText += textElements[i].textContent.trim() + ' ';
        }
        
        if (subtitlesText.trim()) {
          return subtitlesText.trim();
        }
      }
    } catch (apiError) {
      console.error('Error with direct API request:', apiError);
    }
  } catch (error) {
    console.error('Error getting subtitles from player data:', error);
  }
  
  console.log('Could not get subtitles from player data');
  return null;
}

/**
 * Helper function to find transcript data in YouTube's initialData
 */
function findTranscriptDataInInitialData(data) {
  // This is a recursive function to search through the complex nested structure
  function searchForTranscriptData(obj, path = '') {
    if (!obj || typeof obj !== 'object') return null;
    
    // Look for transcript content
    if (obj.transcriptSearchPanelRenderer || 
        obj.transcriptRenderer || 
        (obj.contentRenderer && obj.contentRenderer.transcriptRenderer)) {
      console.log(`Found transcript data at path: ${path}`);
      
      // Extract the actual transcript text
      let transcriptItems = [];
      
      if (obj.transcriptSearchPanelRenderer && obj.transcriptSearchPanelRenderer.body) {
        transcriptItems = obj.transcriptSearchPanelRenderer.body.transcriptSegmentListRenderer?.initialSegments || [];
      } else if (obj.transcriptRenderer) {
        transcriptItems = obj.transcriptRenderer.body?.transcriptSegmentListRenderer?.initialSegments || [];
      } else if (obj.contentRenderer && obj.contentRenderer.transcriptRenderer) {
        transcriptItems = obj.contentRenderer.transcriptRenderer.body?.transcriptSegmentListRenderer?.initialSegments || [];
      }
      
      if (transcriptItems.length > 0) {
        let subtitlesText = '';
        
        for (const item of transcriptItems) {
          if (item.transcriptSegmentRenderer && item.transcriptSegmentRenderer.snippet) {
            subtitlesText += item.transcriptSegmentRenderer.snippet.runs.map(run => run.text).join(' ') + ' ';
          }
        }
        
        if (subtitlesText.trim()) {
          return subtitlesText.trim();
        }
      }
    }
    
    // Recursively search through all properties
    for (const key in obj) {
      if (obj.hasOwnProperty(key)) {
        const result = searchForTranscriptData(obj[key], `${path}.${key}`);
        if (result) return result;
      }
    }
    
    return null;
  }
  
  return searchForTranscriptData(data);
}

// Get YouTube video ID from URL
function getYouTubeVideoId() {
  const urlParams = new URLSearchParams(window.location.search);
  return urlParams.get('v');
} 